package org.fall.controller;

import org.fall.api.MySQLRemoteService;
import org.fall.api.RedisRemoteService;
import org.fall.config.ShortMessageProperties;
import org.fall.constant.CrowdConstant;
import org.fall.entity.po.MemberPO;
import org.fall.entity.vo.MemberVO;
import org.fall.util.CrowdUtil;
import org.fall.util.ResultEntity;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import java.util.Objects;
import java.util.concurrent.TimeUnit;


@Controller
public class MemberController {
    @Autowired
    private ShortMessageProperties shortMessageProperties;
    @Autowired
    private RedisRemoteService redisRemoteService;
    @Autowired
    private MySQLRemoteService mySQLRemoteService;

    @ResponseBody
    @RequestMapping("/auth/member/send/short/message.json")
    public ResultEntity<String> sendMessage(@RequestParam("phoneNum") String phoneNum) {

        // 1.发送验证码到phoneNum手机
        ResultEntity<String> sendMessageResultEntity = CrowdUtil.sendCodeByShortMessage(
                shortMessageProperties.getHost(),
                shortMessageProperties.getPath(),
                shortMessageProperties.getMethod(), phoneNum,
                shortMessageProperties.getAppCode(),
                shortMessageProperties.getSmsSignId(),
                shortMessageProperties.getTemplateId());

        // 2.判断短信发送结果
        if (ResultEntity.SUCCESS.equals(sendMessageResultEntity.getResult())) {
            // 3.如果发送成功，则将验证码存入Redis
            // ①从上一步操作的结果中获取随机生成的验证码
            String code = sendMessageResultEntity.getData();

            // ②拼接一个用于在Redis中存储数据的key
            String key = CrowdConstant.REDIS_CODE_PREFIX + phoneNum;

            // ③调用远程接口存入Redis
            ResultEntity<String> saveCodeResultEntity = redisRemoteService.setRedisKeyValueWithTimeoutRemote(key, code, 15, TimeUnit.MINUTES);

            // ④判断结果
            if (ResultEntity.SUCCESS.equals(saveCodeResultEntity.getResult())) {

                return ResultEntity.successWithoutData();
            } else {
                return saveCodeResultEntity;
            }
        } else {
            return sendMessageResultEntity;
        }

    }

    @RequestMapping(value = "/auth/member/do/register")
    public String register(MemberVO memberVO, ModelMap modelMap) {
//获取用户输入的手机号
        String phoneNum = memberVO.getPhoneNum();
        //拼Redis中储存的验证码的key
        String key = CrowdConstant.REDIS_CODE_PREFIX + phoneNum;
        //读取value
        ResultEntity<String> resultEntity = redisRemoteService.getRedisValueByKeyRemote(key);
        // 判断获取redis中的验证码是否成功
        if (ResultEntity.FAILED.equals(resultEntity)) {
            // 失败，返回主页页面
            modelMap.addAttribute(CrowdConstant.ATTR_NAME_MESSAGE, resultEntity.getMessage());
            return "member-reg";
        }

        // 获取redis中的验证码的值
        String redisCode = resultEntity.getData();
        if (redisCode == null) {
            modelMap.addAttribute(CrowdConstant.ATTR_NAME_MESSAGE, CrowdConstant.MESSAGE_CODE_NOT_EXIST);
            return "member-reg";
        }

        // 获取表单提交的验证码
        String formCode = memberVO.getCode();

        // 如果redis中的验证码与表单提交的验证码不同
        if (!Objects.equals(formCode, redisCode)) {
            // request域存入不匹配的message
            modelMap.addAttribute(CrowdConstant.ATTR_NAME_MESSAGE, CrowdConstant.MESSAGE_CODE_INVALID);
            // 返回注册页面
            return "member-reg";
        }

        // 验证码比对一致，删除redis中的验证码数据
        redisRemoteService.removeRedisKeyByKeyRemote(key);

        // 进行注册操作

        // 1、加密
        BCryptPasswordEncoder bCryptPasswordEncoder = new BCryptPasswordEncoder();
        String formPwd = memberVO.getUserPswd();
        String encode = bCryptPasswordEncoder.encode(formPwd);

        // 2、将加密后的密码放入MemberVO对象
        memberVO.setUserPswd(encode);

        // 3、执行保存
        MemberPO memberPO = new MemberPO();
        BeanUtils.copyProperties(memberVO, memberPO);
        ResultEntity<String> saveResultEntity = mySQLRemoteService.saveMember(memberPO);

        // 4、判断保存是否成功
        String saveResult = saveResultEntity.getResult();
        if (ResultEntity.FAILED.equals(saveResult)) {
            // 保存失败，则返回保存操作的ResultEntity中的message，存入request域的message
            modelMap.addAttribute(CrowdConstant.ATTR_NAME_MESSAGE, saveResultEntity.getMessage());
            // 回到注册页面
            return "member-reg";
        }

        // 全部判断成功，跳转到登录页面
        return "redirect:http://localhost/auth/to/member/login/page.html";
    }
}